Detect cyclic dependencies through [replace]
authorAlex Crichton <alex@alexcrichton.com>
Mon, 20 Mar 2017 19:43:44 +0000 (12:43 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Mon, 20 Mar 2017 19:46:17 +0000 (12:46 -0700)
Previously this'd cause a stack overflow in Cargo later in the compilation
graph, but this is intended to get caught during resolution.

Closes #3831

src/cargo/core/resolver/mod.rs
tests/overrides.rs

index 4943f6fe2fa55786d161279a3f19bd020957b864..40bb734db5b06d6fdc91dd9084ca18f9a73c9f89 100644 (file)
@@ -1023,13 +1023,17 @@ fn check_cycles(resolve: &Resolve,
         // dependencies.
         if checked.insert(id) {
             let summary = summaries[id];
-            for dep in resolve.deps(id) {
+            for dep in resolve.deps_not_replaced(id) {
                 let is_transitive = summary.dependencies().iter().any(|d| {
                     d.matches_id(dep) && d.is_transitive()
                 });
                 let mut empty = HashSet::new();
                 let visited = if is_transitive {&mut *visited} else {&mut empty};
                 visit(resolve, dep, summaries, visited, checked)?;
+
+                if let Some(id) = resolve.replacement(dep) {
+                    visit(resolve, id, summaries, visited, checked)?;
+                }
             }
         }
 
index 4095cedf22a74013fd7205ac09181da0cec037f7..24d84190535e47cecfebd8c590c9bb00cf3d86f7 100644 (file)
@@ -1162,3 +1162,38 @@ fn override_with_default_feature() {
     assert_that(p.cargo_process("run"),
                 execs().with_status(0));
 }
+
+#[test]
+fn override_plus_dep() {
+    Package::new("bar", "0.1.0").publish();
+
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            version = "0.0.1"
+            authors = []
+
+            [dependencies]
+            bar = "0.1"
+
+            [replace]
+            'bar:0.1.0' = { path = "bar" }
+        "#)
+        .file("src/lib.rs", "")
+        .file("bar/Cargo.toml", r#"
+            [package]
+            name = "bar"
+            version = "0.1.0"
+            authors = []
+
+            [dependencies]
+            foo = { path = ".." }
+        "#)
+        .file("bar/src/lib.rs", "");
+
+    assert_that(p.cargo_process("build"),
+                execs().with_status(101).with_stderr_contains("\
+error: cyclic package dependency: [..]
+"));
+}